package ltd.bugs.cute.common.rsa;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

import ltd.bugs.cute.common.util.IOUtils;

/**
 * key的初始工具类
 * 
 * @author zhengzhq
 *
 */
public class KeyInitialzer {

  public static final String ALGORITHM_RSA = "RSA";
  public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";

  /**
   * 初始化公有key
   * 
   * @param keyFile key文件
   * @param algorithm 算法
   * @return
   * @throws Exception
   */
  public static RSAPublicKey initPublicKey(File keyFile) throws Exception {
    return initPublicKey(readKeyFileToString(keyFile));
  }

  /**
   * 初始化公有key
   * 
   * @param publicKey 公有key
   * @param algorithm 算法
   * @return
   * @throws Exception
   */
  public static RSAPublicKey initPublicKey(String publicKey) {
    try {
      X509EncodedKeySpec pubX509 =
          new X509EncodedKeySpec(Base64.decodeBase64(trimComments(publicKey)));
      KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);

      return (RSAPublicKey) keyFactory.generatePublic(pubX509);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 初始化私有key
   * 
   * @param keyFile key文件
   * @param algorithm 算法
   * @return
   * @throws Exception
   */
  public static RSAPrivateKey initPrivateKey(File keyFile) {
    return initPrivateKey(readKeyFileToString(keyFile));
  }

  /**
   * 初始化私有key
   * 
   * @param privateKey 私有key
   * @param algorithm 算法
   * @return
   * @throws Exception
   */
  public static RSAPrivateKey initPrivateKey(String privateKey) {
    try {
      PKCS8EncodedKeySpec priPKCS8 =
          new PKCS8EncodedKeySpec(Base64.decodeBase64(trimComments(privateKey)));
      KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);

      return (RSAPrivateKey) keyFactory.generatePrivate(priPKCS8);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  private static String trimComments(String data) {
    if (data == null) {
      return null;
    }

    String[] arr = data.split("\\n");
    StringBuilder builder = new StringBuilder();
    for (String str : arr) {
      if (str.charAt(0) == '-') {
        continue;
      }
      builder.append(str);
      builder.append('\r');
    }

    return builder.toString();
  }

  /**
   * 读取加密文件并返回内容，过滤--部分
   * 
   * @param keyFile
   * @return
   */
  private static String readKeyFileToString(File keyFile) {
    BufferedReader reader = null;

    try {
      reader = new BufferedReader(new InputStreamReader(new FileInputStream(keyFile)));
      StringBuilder builder = new StringBuilder();
      String readLine = null;
      while ((readLine = reader.readLine()) != null) {
        if (readLine.charAt(0) == '-') {
          continue;
        } else {
          builder.append(readLine);
          builder.append('\r');
        }
      }

      return builder.toString();
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      if (reader != null) {
        IOUtils.closeQuietly(reader);
      }
    }
  }
}
